home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / etc / hotplug / usb.agent < prev    next >
Text File  |  2006-05-01  |  13KB  |  453 lines

  1. #!/bin/sh
  2. #
  3. # USB-specific hotplug policy agent.
  4. #
  5. # This should handle 2.2.18+, 2.4.*, and 2.5.* USB hotplugging,
  6. # with a consistent framework for adding device and driver
  7. # specific handling.
  8. #
  9. # Normally, adding a usb device will modprobe a driver.  If there
  10. # is a /etc/hotplug/usb/$DRIVER script set up, it will also run,
  11. # handling tasks like loading firmware or starting daemons.
  12. #
  13. # Kernel USB hotplug params include:
  14. #    
  15. #    ACTION=%s [add or remove]
  16. #    DEVPATH=%s [in 2.5 kernels, /sys/$DEVPATH]
  17. #    PRODUCT=%x/%x/%x
  18. #    INTERFACE=%d/%d/%d [ for interface 0, if TYPE=0/*/* ]
  19. #    TYPE=%d/%d/%d
  20. #
  21. # And if usbfs (originally called usbdevfs) is configured, also:
  22. #
  23. #    DEVFS=/proc/bus/usb [gone in 2.5]
  24. #    DEVICE=/proc/bus/usb/%03d/%03d
  25. #
  26. # This script then adds the variable:
  27. #
  28. #       REMOVER=/var/run/usb/<some string unique to $DEVICE>
  29. #
  30. # This is the path where the script would like to find a remover, if
  31. # the target device needs one. This script is executed on remove if
  32. # it is executable when the remove happens.
  33. #
  34. # If usbfs is mounted on /proc/bus/usb, $DEVICE is a file which
  35. # can be read to get the device's current configuration descriptor.
  36. # (The "usbmodules" utility does that.)  Or it can be used by a
  37. # user mode driver to interact with the usb device.  USB hotplug
  38. # does *not* require usbfs (or sysfs) to work, although on 2.4
  39. # some devices work better if "usbmodules" can help.
  40. #
  41. # For Linux 2.5+ kernels, there's no need for "usbmodules".  For
  42. # two reasons:  first, hotplug is invoked for each interface, not
  43. # just the first one.  Second, sysfs exposes descriptors so they
  44. # are easy to use for "coldplug" event simulation.  (But sysfs is
  45. # not a replacement for the driver I/O capabilities in usbfs.)
  46. #
  47. # On systems using Linux 2.4.* kernels, be sure to use the right
  48. # modutils (2.4.2+).  That ensures that hotplugging uses the list
  49. # of modules installed for your kernel, rather than the one that's
  50. # included here for use on systems without MODULE_DEVICE_TABLE
  51. # support.
  52. #
  53. #
  54. # HISTORY:
  55. #
  56. # 20-Nov-2002    some 2.5 updates; handle new 'device' hotplug; turn off
  57. #        'sleep' hack since hcds must all queue control traffic
  58. # 08-Aug-2002    support for multiple usermaps (maxk), minor cleanup
  59. # 18-Jan-2002    fix match algorithm in usb_map_modules()
  60. # 14-Jan-2002    fix work around 2.2 brokeness of $PRODUCT
  61. # 09-Jan-2002    REMOVER for system without usbdevfs
  62. #
  63. # 14-Mar-2001    Cleanup, bitmask the match_flags
  64. # 26-Feb-2001    Cleanup, support comments (Gioele Barabucci)
  65. # 15-Feb-2001    Remove use of "<<" (Adam Richter)
  66. # 23-Jan-2001    Update 2.2 handling; unfortunately there's no "feature
  67. #        test" that can work robustly
  68. # 05-Jan-2001    Quick hack for kernel 2.4.0 and modutils 2.4.1
  69. # 03-Jan-2001    Initial version of "new" hotplug agent, using feedback
  70. #        and contributions from Adam Richter, Ryan VanderBijl,
  71. #        Norbert Preining, Florian Lohoff, David Brownell and
  72. #        others.  To replace the original /etc/usb/policy. (db)
  73. #
  74. # $Id: usb.agent,v 1.43 2004/09/20 22:50:11 kroah Exp $
  75. #
  76.  
  77. if [ -f /etc/sysconfig/usb ]; then
  78.     . /etc/sysconfig/usb
  79. fi
  80. if [ -f /etc/conf.d/usb ]; then
  81.     . /etc/conf.d/usb
  82. fi
  83.  
  84. cd /etc/hotplug
  85. . ./hotplug.functions
  86. # DEBUG=yes export DEBUG
  87.  
  88. # generated by modutils, for current 2.4.x (and later) kernels
  89. MAP_CURRENT=$MODULE_DIR/modules.usbmap
  90.  
  91. # used if MAP_CURRENT is missing; for 2.2.x kernels
  92. MAP_DISTMAP=$HOTPLUG_DIR/usb.distmap
  93.  
  94. #
  95. # used for kernel drivers that don't show up in CURRENT or DISTMAP,
  96. # currently input drivers (joysticks, keyboards, etc).  newer systems
  97. # should use input hotplug events instead.
  98. #
  99. MAP_HANDMAP=$HOTPLUG_DIR/usb.handmap
  100.  
  101. #
  102. # used to run config scripts for user mode drivers (jPhoto, gPhoto2,
  103. # rio500 tools, etc) ... instead of naming kernel modules, it names
  104. # config scripts.  those could change $DEVICE permissions, etc.
  105. #
  106. # for purely user mode drivers, scripts $HOTPLUG_DIR/usb/NAME should be
  107. # installed with usermap files in $HOTPLUG_DIR/usb/NAME.usermap instead
  108. # of continuing to use/modify $MAP_USERMAP 
  109. #
  110. MAP_USERMAP=$HOTPLUG_DIR/usb.usermap
  111.  
  112.  
  113. # accumulates list of modules we may care about
  114. DRIVERS=""
  115.  
  116. if [ "$ACTION" = "" ]; then
  117.     mesg Bad USB agent invocation, no action
  118.     exit 1
  119. fi
  120.  
  121. # starting in kernel 2.5 there are two kinds of USB hotplug events.
  122. # - per-interface; 2.2/2.4 kernels only reported the first one.
  123. #    "new" events have nonzero /sys/$DEVPATH/bInterfaceNumber
  124. # - per-device; "new" events don't have $PRODUCT
  125. SYSFS=/sys
  126. if [ "$PRODUCT" = "" ]; then
  127.     # this is either an error, or we're on a 2.5 system...
  128.     if [ "$DEVPATH" = "" ]; then
  129.     mesg Bad USB agent invocation
  130.     exit 1
  131.     fi
  132.  
  133.     # sysfs files may already be gone
  134.     if [ $ACTION = 'remove' ]; then
  135.     exit 0
  136.     fi
  137.  
  138.     # we could be running before usb populated these attributes...
  139.     if [ ! -f $SYSFS/$DEVPATH/bNumConfigurations ]; then
  140.     # FIXME wait till they appear, or N seconds elapse
  141.     sleep 2
  142.     fi
  143.  
  144.     # this could care about changing the default config, or warning
  145.     # when the user hooked a fast device up so it runs slowly.
  146.     if [ ! -f $SYSFS/$DEVPATH/bNumConfigurations ]; then
  147.     exit 0
  148.     fi
  149.     TMP=$(cat $SYSFS/$DEVPATH/bNumConfigurations)
  150.     if [ $TMP -ne 1 ] && [ "$ACTION" = add ]; then
  151.     mesg Keeping default configuration with $SYSFS/$DEVPATH
  152.     fi
  153.  
  154.     # NOTE:  it might be good to add an extension hook here rather
  155.     # than ignore these events, but even device-scope tasks such
  156.     # as firmware download can still use the interface-0 event
  157.     # (as they did with 2.2/2.4 hotplug setup scripts).
  158.     exit 0
  159. fi
  160.  
  161. # we can't "unset IFS" on bash1, so save a copy
  162. DEFAULT_IFS="$IFS"
  163.  
  164. #
  165. # Each modules.usbmap format line corresponds to one entry in a
  166. # MODULE_DEVICE_TABLE(usb,...) declaration in a kernel file.
  167. #
  168. # Think of it as a database column with up to three "match specs"
  169. # to associate kernel modules with particular devices or classes
  170. # of device.  The match specs provide a reasonably good filtering
  171. # mechanism, but some driver probe() routines need to provide
  172. # extra filtering.
  173. #
  174.  
  175. usb_convert_vars ()
  176. {
  177.     # work around 2.2.early brokenness
  178.     # munges the usb_bcdDevice such that it is a integer rather
  179.     # than a float: e.g. 1.0 become 0100
  180.     PRODUCT=`echo $PRODUCT | sed -e "s+\.\([0-9]\)$+.\10+" -e "s/\.$/00/" \
  181.                                   -e "s+/\([0-9]\)\.\([0-9][0-9]\)+/0\1\2+" \
  182.               -e "s+/\([0-9][0-9]\)\.\([0-9][0-9]\)+/\1\2+"`
  183.     set $(echo $PRODUCT | sed -e 's+\([^/]*\)/\([^/]*\)/\(.*\)+\1 \2 \3+')
  184.     usb_idVendor=$((0x$1))
  185.     usb_idProduct=$((0x$2))
  186.     usb_bcdDevice=$((0x$3))
  187.  
  188.     if [ "$TYPE" != "" ]; then
  189.         IFS=/
  190.         set $TYPE ''
  191.     usb_bDeviceClass=$1
  192.         usb_bDeviceSubClass=$2
  193.         usb_bDeviceProtocol=$3
  194.     IFS="$DEFAULT_IFS"
  195.     elif [ -r $SYSFS/$DEVPATH/bDeviceClass ]; then
  196.     usb_bDeviceClass=$((0x$(cat $SYSFS/$DEVPATH/bDeviceClass)))
  197.     usb_bDeviceSubClass=$((0x$(cat $SYSFS/$DEVPATH/bDeviceSubClass)))
  198.     usb_bDeviceProtocol=$((0x$(cat $SYSFS/$DEVPATH/bDeviceProtocol)))
  199.     else
  200.     # out-of-range values
  201.     usb_bDeviceClass=1000
  202.     usb_bDeviceSubClass=1000
  203.     usb_bDeviceProtocol=1000
  204.     fi
  205.  
  206.     if [ "$INTERFACE" != "" ]; then
  207.     IFS=/
  208.     set $INTERFACE ''
  209.     usb_bInterfaceClass=$1
  210.     usb_bInterfaceSubClass=$2
  211.         usb_bInterfaceProtocol=$3
  212.     IFS="$DEFAULT_IFS"
  213.     elif [ -r $SYSFS/$DEVPATH/bInterfaceClass ]; then
  214.     usb_bInterfaceClass=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceClass)))
  215.     usb_bInterfaceSubClass=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceSubClass)))
  216.     usb_bInterfaceProtocol=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceProtocol)))
  217.     else
  218.     # out-of-range values
  219.     usb_bInterfaceClass=1000
  220.     usb_bInterfaceSubClass=1000
  221.     usb_bInterfaceProtocol=1000
  222.     fi
  223. }
  224.  
  225. USB_MATCH_VENDOR=$((0x0001))
  226. USB_MATCH_PRODUCT=$((0x0002))
  227. USB_MATCH_DEV_LO=$((0x0004))
  228. USB_MATCH_DEV_HI=$((0x0008))
  229. USB_MATCH_DEV_CLASS=$((0x0010))
  230. USB_MATCH_DEV_SUBCLASS=$((0x0020))
  231. USB_MATCH_DEV_PROTOCOL=$((0x0040))
  232. USB_MATCH_INT_CLASS=$((0x0080))
  233. USB_MATCH_INT_SUBCLASS=$((0x0100))
  234. USB_MATCH_INT_PROTOCOL=$((0x0200))
  235.  
  236. #
  237. # stdin is "modules.usbmap" syntax
  238. # on return, all matching modules were added to $DRIVERS
  239. #
  240. usb_map_modules ()
  241. {
  242.     # look at each usb_device_id entry
  243.     # collect all matches in $DRIVERS
  244.  
  245.     while read line
  246.     do
  247.         # comments are lines that start with "#" ...
  248.     # be careful, they still get parsed by bash!
  249.     case "$line" in
  250.     \#*) continue ;;
  251.     "") continue ;;
  252.     esac
  253.  
  254.     set $line
  255.  
  256.     module=$1
  257.     match_flags=$(($2))
  258.  
  259.     idVendor=$(($3))
  260.     idProduct=$(($4))
  261.     bcdDevice_lo=$(($5))
  262.     bcdDevice_hi=$(($6))
  263.  
  264.     bDeviceClass=$(($7))
  265.     bDeviceSubClass=$(($8))
  266.     bDeviceProtocol=$(($9))
  267.  
  268.     shift 9
  269.     bInterfaceClass=$(($1))
  270.     bInterfaceSubClass=$(($2))
  271.     bInterfaceProtocol=$(($3))
  272.  
  273.     : checkmatch $module
  274.  
  275.     : idVendor $idVendor $usb_idVendor
  276.         if [ $USB_MATCH_VENDOR -eq $(( $match_flags & $USB_MATCH_VENDOR )) ] && 
  277.        [ $idVendor -ne $usb_idVendor ]; then
  278.         continue
  279.     fi
  280.  
  281.     : idProduct $idProduct $usb_idProduct
  282.     if [ $USB_MATCH_PRODUCT -eq $(( $match_flags & $USB_MATCH_PRODUCT )) ] &&
  283.        [ $idProduct -ne $usb_idProduct ]; then
  284.         continue
  285.     fi
  286.  
  287.     : bcdDevice range $bcdDevice_hi $bcdDevice_lo actual $usb_bcdDevice
  288.     if [ $USB_MATCH_DEV_LO -eq $(( $match_flags & $USB_MATCH_DEV_LO )) ] &&
  289.        [ $usb_bcdDevice -lt $bcdDevice_lo ]; then
  290.         continue
  291.     fi
  292.  
  293.     # bcdDevice_lo <= bcdDevice <= bcdDevice_hi
  294.     if [ $USB_MATCH_DEV_HI -eq $(( $match_flags & $USB_MATCH_DEV_HI )) ] &&
  295.        [ $usb_bcdDevice -gt $bcdDevice_hi ]; then
  296.         continue
  297.     fi
  298.  
  299.     : bDeviceClass $bDeviceClass $usb_bDeviceClass
  300.     if [ $USB_MATCH_DEV_CLASS -eq $(( $match_flags & $USB_MATCH_DEV_CLASS )) ] &&
  301.        [ $bDeviceClass -ne $usb_bDeviceClass ]; then
  302.         continue
  303.     fi
  304.     : bDeviceSubClass $bDeviceSubClass $usb_bDeviceSubClass
  305.     if [ $USB_MATCH_DEV_SUBCLASS -eq $(( $match_flags & $USB_MATCH_DEV_SUBCLASS )) ] &&
  306.        [ $bDeviceSubClass -ne $usb_bDeviceSubClass ]; then
  307.         continue
  308.     fi
  309.     : bDeviceProtocol $bDeviceProtocol $usb_bDeviceProtocol
  310.     if [ $USB_MATCH_DEV_PROTOCOL -eq $(( $match_flags & $USB_MATCH_DEV_PROTOCOL )) ] &&
  311.        [ $bDeviceProtocol -ne $usb_bDeviceProtocol ]; then
  312.         continue
  313.     fi
  314.  
  315.     # NOTE:  for now, this only checks the first of perhaps
  316.     # several interfaces for this device.
  317.  
  318.     : bInterfaceClass $bInterfaceClass $usb_bInterfaceClass
  319.     if [ $USB_MATCH_INT_CLASS -eq $(( $match_flags & $USB_MATCH_INT_CLASS )) ] &&
  320.        [ $bInterfaceClass -ne $usb_bInterfaceClass ]; then
  321.         continue
  322.     fi
  323.     : bInterfaceSubClass $bInterfaceSubClass $usb_bInterfaceSubClass
  324.     if [ $USB_MATCH_INT_SUBCLASS -eq $(( $match_flags & $USB_MATCH_INT_SUBCLASS )) ] &&
  325.        [ $bInterfaceSubClass -ne $usb_bInterfaceSubClass ]; then
  326.         continue
  327.     fi
  328.     : bInterfaceProtocol $bInterfaceProtocol $usb_bInterfaceProtocol
  329.     if [ $USB_MATCH_INT_PROTOCOL -eq $(( $match_flags & $USB_MATCH_INT_PROTOCOL )) ] &&
  330.        [ $bInterfaceProtocol -ne $usb_bInterfaceProtocol ]; then
  331.         continue
  332.     fi
  333.  
  334.     # It was a match!
  335.     DRIVERS="$module $DRIVERS"
  336.     : drivers $DRIVERS
  337.     done
  338. }
  339.  
  340. #
  341. # declare a REMOVER name that the add action can use to create a
  342. # remover, or that the remove action can use to execute a remover.
  343. #
  344. if [ "$DEVPATH" != "" ]; then
  345.   # probably, 2.6.x
  346.   REMOVER=/var/run/usb/$(readlink -f $SYSFS/$DEVPATH | sed -e 's;/;%;g')
  347. elif [ "$DEVICE" != "" ]; then
  348.   # 2.4.x?
  349.   REMOVER=/var/run/usb/$(echo $DEVICE | sed -e 's;/;%;g')
  350. else
  351.   # should not happen?
  352.   REMOVER=/var/run/usb/$(echo "$INTERFACE/$PRODUCT/$TYPE" | sed -e 's;/;%;g')
  353. fi
  354. export REMOVER
  355.  
  356. #
  357. # What to do with this USB hotplug event?
  358. #
  359. case $ACTION in
  360.  
  361. add)
  362.     # partial workaround for 2.4 uhci/usb-uhci driver problem:  they don't
  363.     # queue control requests, so device drivers can confuse each other if
  364.     # they happen to issue requests at the same time ... it happens easily
  365.     # with slow HID devices and "usbmodules".
  366.     # starting with 2.5 (DEVPATH set), all hcds must queue control traffic.
  367.     if [ "$DEVPATH" = "" ]; then
  368.     sleep 3
  369.     fi
  370.  
  371.     usb_convert_vars
  372.  
  373.     FOUND=false
  374.     if [ -f $SYSFS/$DEVPATH/manufacturer ]; then
  375.     LABEL="USB `cat $SYSFS/$DEVPATH/manufacturer` `cat $SYSFS/$DEVPATH/product`"
  376.     else
  377.     LABEL="USB product $PRODUCT"
  378.     fi
  379.  
  380.     if [ -e "$REMOVER" ]; then
  381.     rm -f "$REMOVER"
  382.     fi
  383.  
  384.     # on 2.4 systems, modutils 2.4.2+ maintains MAP_CURRENT
  385.     # ... otherwise we can't rely on it (sigh)
  386.     case "$KERNEL" in
  387.     2.4.*|2.5.*|2.6.*)
  388.     if [ -r $MAP_CURRENT ]; then
  389.         load_drivers usb $MAP_CURRENT "$LABEL"
  390.     fi;;
  391.     *)
  392.     if [ -r $MAP_DISTMAP ]; then
  393.         load_drivers usb $MAP_DISTMAP "$LABEL"
  394.     fi;;
  395.     esac
  396.     if [ "$DRIVERS" != "" ]; then
  397.     FOUND=true
  398.     fi
  399.  
  400.     # cope with special driver module configurations
  401.     # (mostly HID devices, until we have an input.agent)
  402.     # not needed on 2.6 - they are loaded by hotplug
  403.     case "$KERNEL" in
  404.     2.6.* )
  405.         : nothing
  406.     ;;
  407.     * )
  408.         if [ -r $MAP_HANDMAP ]; then
  409.         load_drivers usb $MAP_HANDMAP "$LABEL"
  410.         if [ "$DRIVERS" != "" ]; then
  411.             FOUND=true
  412.         fi
  413.         fi
  414.     ;;
  415.     esac
  416.  
  417.     # some devices have user-mode drivers (no kernel module, but config)
  418.     # or specialized user-mode setup helpers 
  419.     MODPROBE=:
  420.     for MAP in $MAP_USERMAP $HOTPLUG_DIR/usb/*.usermap
  421.     do
  422.         if [ -r $MAP ]; then
  423.         load_drivers usb $MAP "$LABEL"
  424.         if [ "$DRIVERS" != "" ]; then
  425.         FOUND=true
  426.         fi
  427.     fi
  428.     done
  429.  
  430.     if [ "$FOUND" = "false" ]; then
  431.     debug_mesg "... no modules for $LABEL"
  432.     exit 2
  433.     fi
  434.     ;;
  435.  
  436. remove)
  437.     if [ -x $REMOVER ]; then
  438.     $REMOVER
  439.     fi
  440.     rm -f $REMOVER
  441.  
  442.     if [ -x /usr/sbin/updfstab ]; then
  443.         /usr/sbin/updfstab
  444.     fi
  445.     ;;
  446.  
  447. *)
  448.     debug_mesg USB $ACTION event not supported
  449.     exit 1
  450.     ;;
  451.  
  452. esac
  453.